package cn.dakaqi.sys.topic.services;

import cn.dakaqi.entities.GroupRecruit;
import cn.dakaqi.entities.IndexData;
import cn.dakaqi.utils.DKQConstant;
import cn.dakaqi.utils.exception.ServiceRuntimeException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;

import javax.persistence.criteria.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by chunyang on 2016/4/29.
 */
@Component(value = "indexDataService")
public class IndexDataServiceImpl implements IndexDataService
{
    @Autowired
    IndexDataDao indexDataDao;

    @Override
    public void save(IndexData data) throws ServiceRuntimeException
    {
        indexDataDao.save(data);
    }

    @Override
    public void update(IndexData data) throws ServiceRuntimeException
    {
        indexDataDao.save(data);
    }

    @Override
    public IndexData findOne(Long id) throws ServiceRuntimeException
    {
        return indexDataDao.findOne(id);
    }

    @Override
    public Page<IndexData> findAll(final String city, final String job, final String serviceField, final String skills, int pageNumber) throws ServiceRuntimeException
    {
//        Sort sort = new Sort(Sort.Direction.DESC, "top,createTime");
//        PageRequest pageRequest = new PageRequest(pageNumber - 1, 10, sort);
//        Map<String, SearchFilter> filters = Maps.newHashMap();
//        if(StringUtils.isNotBlank(city))
//            filters.put("city", new SearchFilter("city", SearchFilter.Operator.LIKE, city));
//        if(StringUtils.isNotBlank(job))
//        {
//            String[] fields = job.split(";");
//            for(String field:fields)
//                filters.put("job", new SearchFilter("job", SearchFilter.Operator.LIKE, field));
//        }
//        if(StringUtils.isNotBlank(serviceField))
//        {
//            String[] fields = serviceField.split(";");
//            for(String field:fields)
//                filters.put("serviceField", new SearchFilter("serviceField", SearchFilter.Operator.LIKE, field));
//        }
//        if(StringUtils.isNotBlank(skills))
//        {
//            String[] temp = skills.split(";");
//            for(String skill:temp)
//                filters.put("skill", new SearchFilter("skill", SearchFilter.Operator.LIKE, skill));
//        }
//
//        Specification<IndexData> spec = DynamicSpecifications.bySearchFilter(filters.values(), IndexData.class);
//        return this.indexDataDao.findAll(spec,pageRequest);

        Sort sort = new Sort(Sort.Direction.DESC,"createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);
        return this.indexDataDao.findAll(new Specification<IndexData>()
        {
            @Override
            public Predicate toPredicate(Root<IndexData> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
            {
                Predicate predicate = null;

                //path转化
                List<Predicate> orPredicates = Lists.newArrayList();

                Path<String> _city = root.get("city");
                Path<String> _job = root.get("job");
                Path<String> _serviceField = root.get("serviceField");
                Path<String> _skills = root.get("skill");
                Path<String> _top = root.get("top");
                Path<String> _display = root.get("display");
                Path<String> _delStatus = root.get("delStatus");

                orPredicates.add(criteriaBuilder.or(criteriaBuilder.equal(_top, DKQConstant.TOP_YES)));

                Predicate p1 = criteriaBuilder.equal(_city, city);
                    orPredicates.add(criteriaBuilder.or(p1));

                if(StringUtils.isNotBlank(job))
                {
                    String[] field = job.split(";");
                    for(String field0:field)
                        orPredicates.add(criteriaBuilder.or(criteriaBuilder.equal(_job, field0)));
                }

                if(StringUtils.isNotBlank(serviceField))
                {
                    String[] serviceFields = serviceField.split(";");
                    for(String field1:serviceFields)
                        orPredicates.add(criteriaBuilder.or(criteriaBuilder.equal(_serviceField, field1)));
                }

                if(StringUtils.isNotBlank(skills))
                {
                    String[] fields = skills.split(";");
                    for(String field2:fields)
                        orPredicates.add(criteriaBuilder.or(criteriaBuilder.equal(_skills, field2)));
                }


                // 将所有条件用 and 联合起来
                if (!orPredicates.isEmpty()) {
                    predicate =  criteriaBuilder.or(orPredicates.toArray(new Predicate[orPredicates.size()]));
                }
                if(null != predicate)
                {
                    predicate = criteriaBuilder.and(predicate,criteriaBuilder.and(criteriaBuilder.equal(_delStatus, DKQConstant.DEL_NO)));
                    predicate = criteriaBuilder.and(predicate,criteriaBuilder.and(criteriaBuilder.equal(_display, DKQConstant.DISPLAY_YES)));
                }
//
//                //以下是springside3提供的方法
//                Predicate o = DynamicSpecifications.bySearchFilter(null, IndexData.class).toPredicate(root, criteriaQuery, criteriaBuilder);
//
//                Predicate p = criteriaBuilder.or(orPredicates.toArray(new Predicate[orPredicates.size()]));
//                criteriaQuery.where(p,o);
                return predicate;
            }
        }, pageRequest);
    }

    @Override
    public Page<IndexData> findDefault(int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("delStatus", new SearchFilter("delStatus", SearchFilter.Operator.EQ, DKQConstant.DEL_NO));
        filters.put("display", new SearchFilter("display", SearchFilter.Operator.EQ, DKQConstant.DISPLAY_YES));
        Specification<IndexData> spec = DynamicSpecifications.bySearchFilter(filters.values(), IndexData.class);
        return this.indexDataDao.findAll(spec,pageRequest);
    }

    @Override
    public List<IndexData> findNoEnd() throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("stopStatus", new SearchFilter("stopStatus", SearchFilter.Operator.EQ, 0));
        Specification<IndexData> spec = DynamicSpecifications.bySearchFilter(filters.values(), IndexData.class);
        return this.indexDataDao.findAll(spec);
    }

    @Override
    public void updateStatus()
    {
        SimpleDateFormat DefaultTimeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        List<IndexData> list =  findNoEnd();
        if(null != list && list.size()>0)
        {
            for(IndexData data:list)
            {

                try
                {
                    Date today = new Date();
                    today = DefaultTimeFormatter.parse(DefaultTimeFormatter.format(today));


                    Date endDate = data.getStopTime();
                    today = DefaultTimeFormatter.parse(DefaultTimeFormatter.format(endDate));

                    //检查当是否已结束
                    if(today.after(endDate))
                    {
                        data.setStopStatus(DKQConstant.PROCEED_END);
                        this.indexDataDao.save(data);
                    }

                } catch (ParseException e)
                {
                    e.printStackTrace();
                }

            }
        }
    }
}
